import {HttpClient} from '@angular/common/http';
import {Observable} from 'rxjs';
import {InterceptedResponse} from './intercepted-response';
// import {HttpHeaders} from '@angular/common/http';
// import {Observable,of} from 'rxjs';

export class InterceptorService {

  private http: HttpClient

  constructor() {
  }

  get(url: string, options?: any): Observable<InterceptedResponse> {
    return new Observable<InterceptedResponse>((observer) => {
      this.http.get(url, options).toPromise().then(response => {
        return observer.next(response as any)
      }).catch(err => {
        observer.error(err)
      });
    });
  }

  post(url: string, options?: any): any {
    return this.http.post(url, options)
  }

  //
  // /**
  //  Before interceptor
  //  patata
  //  */
  // addInterceptor(interceptor: any) {
  //   this.interceptors.push(interceptor);
  // }
  //
  // /** Parent overrides **/
  // private httpRequest(request: any): Observable<HttpResponse> {
  //   request.options = this.getOptions(request.options);
  //   request.options.headers = request.options.headers || new HttpHeaders();
  //   return this.runBeforeInterceptors(request)
  //     .flatMap<any, any>((value: any, index: number) => {
  //       // We return an observable that merges the result of the request plus the interceptorOptions we need
  //       return Observable.zip(
  //         super.request(value.url, value.options),
  //         of(value.interceptorOptions),
  //         function (response, options) {
  //           return {
  //             response: response,
  //             interceptorOptions: options
  //           };
  //         }
  //       ).catch((err: any) => {
  //         return of({
  //           response: err,
  //           interceptorOptions: value.interceptorOptions || {}
  //         });
  //       });
  //     })
  //     .catch<any, any>((err: any) => {
  //       // If it's a cancel, create a fake response and pass it to next interceptors
  //       if (err.error == 'cancelled') {
  //         var response = {
  //           body: null,
  //           status: 0,
  //           statusText: 'intercepted',
  //           headers: new HttpHeaders()
  //         }
  //         return of({
  //           response: new HttpResponse(response),
  //           intercepted: true,
  //           interceptorStep: err.position,
  //           interceptorOptions: err.interceptorOptions
  //         });
  //       } else {
  //         // We had an exception in the pipeline... woops? TODO
  //       }
  //     })
  //     .flatMap((value: any, index: number) => {
  //       var startOn = (value.intercepted) ? value.interceptorStep : this.interceptors.length - 1;
  //       return this.runAfterInterceptors(value, startOn);
  //     })
  //     .flatMap((value: any, index: number) => {
  //       return of(value.response);
  //     })
  //     .flatMap((value: HttpResponse, index: number) => {
  //       if (!value.ok)
  //         return Observable.throw(value);
  //
  //       return of(value);
  //     });
  // }
  //
  // request(url: string | HttpRequest, options?: any): Observable<HttpResponse> {
  //   options = options || {};
  //   let responseObservable: any;
  //   if (typeof url === 'string') {
  //     responseObservable = this.httpRequest({
  //       url: url,
  //       options: options,
  //       interceptorOptions: options.interceptorOptions || {}
  //     });
  //   } else if (url instanceof HttpRequest) {
  //     let request: HttpRequest = url;
  //     responseObservable = this.httpRequest({
  //       url: request.url,
  //       options: {
  //         method: request.method,
  //         headers: request.headers,
  //         url: request.url,
  //         withCredentials: request.withCredentials,
  //         responseType: request.responseType,
  //         body: request.getBody()
  //       },
  //       interceptorOptions: options.interceptorOptions || {}
  //     });
  //   } else {
  //     throw new Error('First argument must be a url string or Request instance.');
  //   }
  //   return responseObservable;
  // }
  //
  // getOptions(options ?: any): any {
  //   if (options) {
  //     // Shallow copy to avoid modifying method/url on incoming options
  //     return {...options};
  //   }
  //   return {};
  // }
  //
  // /**
  //  * Performs a request with `get` http method.
  //  */
  // get(url: string, options?: any): Observable<HttpResponse> {
  //   options = this.getOptions(options);
  //   options.method = options.method || 'get';
  //   options.url = options.url || url;
  //   return this.request(url, options);
  // }
  //
  // /**
  //  * Performs a request with `post` http method.
  //  */
  // post(url: string, body: any, options?: any): Observable<HttpResponse> {
  //   options = this.getOptions(options);
  //   options.method = options.method || 'post';
  //   options.url = options.url || url;
  //   options.body = options.body || body;
  //   return this.request(url, options);
  // }
  //
  // /**
  //  * Performs a request with `put` http method.
  //  */
  // put(url: string, body: any, options?: any): Observable<HttpResponse> {
  //   options = this.getOptions(options);
  //   options.method = options.method || 'put';
  //   options.url = options.url || url;
  //   options.body = options.body || body;
  //   return this.request(url, options);
  // }
  //
  // /**
  //  * Performs a request with `delete` http method.
  //  */
  // delete(url: string, options?: any): Observable<HttpResponse> {
  //   options = this.getOptions(options);
  //   options.method = options.method || 'delete';
  //   options.url = options.url || url;
  //   return this.request(url, options);
  // }
  //
  // /**
  //  * Performs a request with `patch` http method.
  //  */
  // patch(url: string, body: any, options?: any): Observable<HttpResponse> {
  //   options = this.getOptions(options);
  //   options.method = options.method || 'patch';
  //   options.url = options.url || url;
  //   options.body = options.body || body;
  //   return this.request(url, options);
  // }
  //
  // /**
  //  * Performs a request with `head` http method.
  //  */
  // head(url: string, options?: any): Observable<HttpResponse> {
  //   options = this.getOptions(options);
  //   options.method = options.method || 'head';
  //   options.url = options.url || url;
  //   return this.request(url, options);
  // }
  //
  // /**
  //  * Performs a request with `options` http method.
  //  */
  // options(url: string, options?: any): Observable<HttpResponse> {
  //   options = this.getOptions(options);
  //   options.method = options.method || 'options';
  //   options.url = options.url || url;
  //   return this.request(url, options);
  // }
  //
  // /** Private functions **/
  // private runBeforeInterceptors(params: any): Observable<any> {
  //   let ret: Observable<any> = of(params);
  //   for (let i = 0; i < this.interceptors.length; i++) {
  //     let bf: any = this.interceptors[i];
  //     if (!bf.interceptBefore) continue;
  //
  //     ret = ret.flatMap<any, any>((value: any, index: number) => {
  //       let newObs: Observable<any>;
  //       let res = null;
  //       try {
  //         res = bf.interceptBefore(value);
  //       } catch (ex) {
  //         console.error(ex);
  //       }
  //       if (!res) newObs = of(value);
  //       else if (!(res instanceof Observable)) newObs = of(<any>res);
  //       else newObs = <any>res;
  //
  //       return newObs.catch((err: any, caught: Observable<any>) => {
  //         if (err == 'cancelled') {
  //           return <Observable<any>><any>Observable.throw({
  //             error: 'cancelled',
  //             interceptorOptions: params.interceptorOptions,
  //             position: i
  //           });
  //         }
  //         return <Observable<any>><any>Observable.throw({
  //           error: 'unknown',
  //           interceptorOptions: params.interceptorOptions,
  //           err: err
  //         });
  //       });
  //     });
  //   }
  //
  //   return ret;
  // }
  //
  // private runAfterInterceptors(response: any, startOn: number): Observable<any> {
  //   let ret: Observable<any> = of(response);
  //
  //   for (let i = startOn; i >= 0; i--) {
  //     let af: any = this.interceptors[i];
  //     if (!af.interceptAfter) continue;
  //
  //     ret = ret.flatMap<any, any>((value: any, index) => {
  //       let newObs: Observable<any>;
  //
  //       let res = null;
  //       try {
  //         res = af.interceptAfter(value);
  //       } catch (ex) {
  //         console.error(ex);
  //       }
  //       if (!res) newObs = of(value);
  //       else if (!(res instanceof Observable)) newObs = of(<any>res);
  //       else newObs = <any>res;
  //
  //       return newObs;
  //     });
  //   }
  //   return ret;
  // }
}

